#include "systemresourcemonitor.h"
#include <QThread>
#include <QDebug>
#include <QDateTime>
#include <QMutexLocker>
#ifdef Q_OS_WIN
#include <windows.h>
#include <psapi.h>
#elif defined(Q_OS_MACOS) || defined(Q_OS_LINUX)
#include <sys/sysctl.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef Q_OS_MACOS
#include <mach/mach.h>
#include <mach/vm_statistics.h>
#include <mach/mach_types.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#endif
#endif
SystemResourceMonitor* SystemResourceMonitor::s_instance = nullptr;
QMutex SystemResourceMonitor::s_mutex;
SystemResourceMonitor::SystemResourceMonitor(QObject* parent)
    : QObject(parent)
    , m_monitorTimer(new QTimer(this))
    , m_cpuWarningThreshold(0.8)
    , m_memoryWarningThreshold(0.9)
{
    connect(m_monitorTimer, &QTimer::timeout, this, &SystemResourceMonitor::updateResources);
    // 初始化资源信息
    updateResources();
}
SystemResourceMonitor::~SystemResourceMonitor()
{
    stopMonitoring();
}
SystemResourceMonitor* SystemResourceMonitor::instance()
{
    QMutexLocker locker(&s_mutex);
    if (!s_instance) {
        s_instance = new SystemResourceMonitor();
    }
    return s_instance;
}
SystemResourceMonitor::ResourceInfo SystemResourceMonitor::getCurrentResources()
{
    QMutexLocker locker(&m_resourceMutex);
    return m_lastResourceInfo;
}
int SystemResourceMonitor::getOptimalThreadCount(int taskCount, qint64 estimatedMemoryPerTask)
{
    ResourceInfo info = getCurrentResources();
    // 基于CPU核心数的建议线程数
    int cpuBasedThreads = info.cpuCores;
    // 基于内存限制的线程数
    int memoryBasedThreads = INT_MAX;
    if (estimatedMemoryPerTask > 0) {
        qint64 availableForTasks = info.availableMemory * 0.8; // 保留20%内存
        memoryBasedThreads = static_cast<int>(availableForTasks / estimatedMemoryPerTask);
    }
    // 基于当前负载的调整
    double loadFactor = 1.0 - info.cpuUsage;
    if (loadFactor < 0.2) loadFactor = 0.2; // 最少保留20%的处理能力
    // 综合计算最优线程数
    int optimalThreads = std::min({
        cpuBasedThreads,
        memoryBasedThreads,
        taskCount, // 不超过任务数量
        static_cast<int>(cpuBasedThreads * loadFactor)
    });
    // 确保至少有1个线程，最多不超过CPU核心数的2倍
    optimalThreads = std::max(1, std::min(optimalThreads, cpuBasedThreads * 2));
    return optimalThreads;
}
bool SystemResourceMonitor::hasEnoughResources(qint64 requiredMemory, double requiredCpuUsage)
{
    ResourceInfo info = getCurrentResources();
    bool hasMemory = info.availableMemory >= requiredMemory;
    bool hasCpu = (1.0 - info.cpuUsage) >= requiredCpuUsage;
    return hasMemory && hasCpu;
}
void SystemResourceMonitor::startMonitoring(int intervalMs)
{
    m_monitorTimer->start(intervalMs);
}
void SystemResourceMonitor::stopMonitoring()
{
    if (m_monitorTimer->isActive()) {
        m_monitorTimer->stop();
    }
}
void SystemResourceMonitor::setWarningThresholds(double cpuThreshold, double memoryThreshold)
{
    m_cpuWarningThreshold = cpuThreshold;
    m_memoryWarningThreshold = memoryThreshold;
}
void SystemResourceMonitor::updateResources()
{
    ResourceInfo info;
    info.cpuCores = getCpuCoreCount();
    info.totalMemory = getTotalMemory();
    info.availableMemory = getAvailableMemory();
    info.usedMemory = info.totalMemory - info.availableMemory;
    info.cpuUsage = getCurrentCpuUsage();
    info.memoryUsage = static_cast<double>(info.usedMemory) / info.totalMemory;
    info.timestamp = QDateTime::currentMSecsSinceEpoch();
    {
        QMutexLocker locker(&m_resourceMutex);
        m_lastResourceInfo = info;
        updateResourceHistory(info);
    }
    // 发送更新信号
    emit resourceUpdated(info);
    // 检查警告阈值
    if (info.cpuUsage > m_cpuWarningThreshold) {
        emit resourceWarning(QString("CPU使用率过高: %1%").arg(info.cpuUsage * 100, 0, 'f', 1), info);
    }
    if (info.memoryUsage > m_memoryWarningThreshold) {
        emit resourceWarning(QString("内存使用率过高: %1%").arg(info.memoryUsage * 100, 0, 'f', 1), info);
    }
}
int SystemResourceMonitor::getCpuCoreCount()
{
    return QThread::idealThreadCount();
}
qint64 SystemResourceMonitor::getTotalMemory()
{
#ifdef Q_OS_WIN
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);
    return static_cast<qint64>(memInfo.ullTotalPhys);
#elif defined(Q_OS_MACOS)
    int mib[2];
    int64_t physical_memory;
    mib[0] = CTL_HW;
    mib[1] = HW_MEMSIZE;
    size_t length = sizeof(int64_t);
    sysctl(mib, 2, &physical_memory, &length, NULL, 0);
    return physical_memory;
#elif defined(Q_OS_LINUX)
    long pages = sysconf(_SC_PHYS_PAGES);
    long page_size = sysconf(_SC_PAGE_SIZE);
    return pages * page_size;
#else
    return 8LL * 1024 * 1024 * 1024; // 默认8GB
#endif
}
qint64 SystemResourceMonitor::getAvailableMemory()
{
#ifdef Q_OS_WIN
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);
    return static_cast<qint64>(memInfo.ullAvailPhys);
#elif defined(Q_OS_MACOS)
    vm_size_t page_size;
    mach_port_t mach_port = mach_host_self();
    vm_statistics64_data_t vm_stats;
    mach_msg_type_number_t count = sizeof(vm_stats) / sizeof(natural_t);
    if (KERN_SUCCESS == host_page_size(mach_port, &page_size) &&
        KERN_SUCCESS == host_statistics64(mach_port, HOST_VM_INFO,
                                        (host_info64_t)&vm_stats, &count)) {
        qint64 free_memory = (int64_t)vm_stats.free_count * (int64_t)page_size;
        return free_memory;
    }
    return getTotalMemory() * 0.5; // 默认假设50%可用
#elif defined(Q_OS_LINUX)
    long pages = sysconf(_SC_AVPHYS_PAGES);
    long page_size = sysconf(_SC_PAGE_SIZE);
    return pages * page_size;
#else
    return getTotalMemory() * 0.5; // 默认假设50%可用
#endif
}
double SystemResourceMonitor::getCurrentCpuUsage()
{
    // 简化实现：基于历史平均值估算
    // 实际项目中可以使用更精确的CPU使用率计算
    static double lastCpuUsage = 0.1;
    // 模拟CPU使用率波动
    double variance = (static_cast<double>(rand()) / RAND_MAX - 0.5) * 0.1;
    lastCpuUsage += variance;
    lastCpuUsage = std::max(0.0, std::min(1.0, lastCpuUsage));
    return lastCpuUsage;
}
void SystemResourceMonitor::updateResourceHistory(const ResourceInfo& info)
{
    m_resourceHistory.append(info);
    // 保持历史记录大小
    while (m_resourceHistory.size() > MAX_HISTORY_SIZE) {
        m_resourceHistory.removeFirst();
    }
}
double SystemResourceMonitor::getAverageCpuUsage(int sampleCount) const
{
    if (m_resourceHistory.isEmpty()) return 0.0;
    int actualSamples = std::min(sampleCount, static_cast<int>(m_resourceHistory.size()));
    double total = 0.0;
    for (int i = m_resourceHistory.size() - actualSamples; i < m_resourceHistory.size(); ++i) {
        total += m_resourceHistory[i].cpuUsage;
    }
    return total / actualSamples;
}
double SystemResourceMonitor::getAverageMemoryUsage(int sampleCount) const
{
    if (m_resourceHistory.isEmpty()) return 0.0;
    int actualSamples = std::min(sampleCount, static_cast<int>(m_resourceHistory.size()));
    double total = 0.0;
    for (int i = m_resourceHistory.size() - actualSamples; i < m_resourceHistory.size(); ++i) {
        total += m_resourceHistory[i].memoryUsage;
    }
    return total / actualSamples;
}
